unit YearClassPlot;

interface


uses DiagramFactory, datacontainer, pganalysistypesunit, apgabstractunit, classes,
   xmlintf, pgseriesunit, chartaxisunit, ifmmemoryunit, math, sysutils, apgabstracttypesunit;

type
   YearClassChart = class(TasacsChart)
   private
      m_Cohort : Integer;
   public
      function CreateChartAxis(Axis : PgAxisType) : APgChartAxis; override;
      function CreateSeries(AOwner : TComponent; PrimaryChartAxis : APgChartAxis; MetaSeries : APgMetaSeries; XIndex : Integer) : APgSeries; override;
      constructor Create(AOwner : TComponent; datacontainer : TasacsDataContainer; iCohort : Integer; DoShowSeriesLegend : Boolean); reintroduce;
      property Cohort : Integer read m_Cohort;
   end; // YearClassChart


   YearClassSeries = class(PgSeries)
   protected
      function GetInternalValue(I : Integer; SeriesVariable : PgSeriesVariable; MetaSeries : ApgMetaSeries) : Double; override;
      function GetShowZeros() : Boolean; override;
   end; // YearClassSeries


   YearClassAgeAxis = class(DsYearAxis)
   protected
      function GetNumDimensionElms : Integer; override;
   end; // YearClassAgeAxis


   YearClassAgeAxisSeries = class(AgeAxisSeries)
   protected
      function GetIntervalName(I : Integer) : string; override;
   end; // YearClassAgeAxisSeries


implementation


//////////////////////////////////
// YearClassChart


function YearClassChart.CreateChartAxis(Axis : PgAxisType) : APgChartAxis;
begin
   case Axis of
      atx:
         Result := YearClassAgeAxis.Create(Self as IChart, Axis);
   else
      Result := PgChartAxis.Create(Self as IChart, Axis);
   end; // case
end; // YearClassChart.CreateChartAxis


function YearClassChart.CreateSeries(AOwner : TComponent; PrimaryChartAxis : APgChartAxis; MetaSeries : APgMetaSeries; XIndex : Integer) : APgSeries;
begin
   Result := nil;
   case PrimaryChartAxis.axis of
      atX:
         if Assigned(MetaSeries) then
           Result := YearClassSeries.Create(AOwner, PrimaryChartAxis, MetaSeries, XIndex)
         else
            Result := YearClassAgeAxisSeries.Create(AOwner, PrimaryChartAxis, MetaSeries, XIndex);
   end; // case
end; // YearClassChart.CreateSeries


constructor YearClassChart.Create(AOwner : TComponent; datacontainer : TasacsDataContainer; iCohort : Integer; DoShowSeriesLegend : Boolean);
var
   M : APgMetaSeries;
   NumSeries : Integer;
   SeriesName : string;
   I, iDs : Integer;
   dsVar : DataSourceVar;
   ShowSeries : Boolean;
begin
   m_Cohort := iCohort;
   inherited Create(AOwner, nil, '', datacontainer);
   Caption := 'Cohort ' + inttostr(datacontainer.BirthYearFromCohort[iCohort]);

   ChartLegend := Caption;
   ShowChartLegend := true;
   ShowSeriesLegend := DoShowSeriesLegend;
   ShowMeanLegend := false;
//      ChartAxis[atX].ShowIntervalSeries := true;
   PlotType := ptCategorySingle;
   chartaxis[atX].ContinuousGroupData := false;
   chartaxis[atX].ShowMinorTick := true;
   chartaxis[atX].ShowMajorGrid := false;
//   chartaxis[aty].DefaultMin := true;
   chartaxis[aty].ShowLabel := false;
   chartaxis[atX].ShowLabel := false;
   //chartaxis[atX].AxisLabelPosition := alpCenter;
//   chartaxis[aty].AxisLabel := 'Age';
   chartaxis[aty].AxisLabelPosition := alpCenter;
   chartaxis[atY].ShowMajorGrid := false;
   chartaxis[aty].DefaultAxisLabel := false;
   chartaxis[aty].DefaultMin := false;
   chartaxis[aty].DefaultMax := false;
   chartaxis[aty].MinValue := 0;
   chartaxis[aty].MaxValue := 1;
   // Setup meta series at y axis:
   NumSeries := 2 + 2 * datacontainer.ds.count;
   with ChartAxis[atY].MetaSeries do
   begin
      for I := 0 to NumSeries - 1 do
      begin
         case I of
            0:
            begin
               SeriesName := 'N';
               ShowSeries := true;
            end;
            1:
            begin
               SeriesName := 'F';
               ShowSeries := true;
            end;
{            2:
            begin
               SeriesName := 'N from catch';
               ShowSeries := false;
            end;}
         else
            iDs := (I - 2) mod datacontainer.ds.count;
            dsVar := DataSourceVar(ord(dsObsRate) + trunc((I - 2) / datacontainer.ds.count));
            SeriesName := datasourcecontainer(datacontainer.ds[iDs]).Key;
            case dsVar of
               dsObsRate: SeriesName := SeriesName + ' OBS';
               dsModRate: SeriesName := SeriesName + ' MOD';
            end; // case
            ShowSeries := iDs = 0;
         end; // case
         M := TasacsMetaSeries.Create(ChartAxis[aty], nil, SeriesName, I + 1);
         M.ShowSeries := ShowSeries;
         Add(Pointer(M));
         M.BarPlot := false;
         (M as IPgChartSelection).GraphLayout.LineWidth[geMarkerLine] := 2;
         M.Scatter := true;
         M.LinePlot := true;
         //{ --- trend view---
         M.SuperTrend := false;
         M.Trend.TrendFunctionType := ftMovAvg;
         //}
      end;
   end;
end; // YearClassChart.Create


///////////////////////////////
// YearClassSeries


function YearClassSeries.GetInternalValue(I : Integer; SeriesVariable : PgSeriesVariable; MetaSeries : ApgMetaSeries) : Double;
var
   S : Integer;
   iYear, iAge, iObsYear, iObsAge, iCohort, iDs : Integer;
   dsc : DataSourceContainer;
   dsVar : DataSourceVar;
   ds : FloatMatrix;
begin
   case SeriesVariable of
      svIntervalDelta:
         with YearClassChart(PrimaryChartAxis.ChartComp) do
         begin
            iCohort := Cohort;
            iYear := datacontainer.FirstYearIndexInCohort[iCohort] + (I + MinCategory);
            iAge := datacontainer.FirstAgeIndexInCohort[iCohort] + (I + MinCategory);
            S := Self.MetaSeries.ChartAxis.MetaSeries.IndexOf(Pointer(Self.MetaSeries));
            case S of
               0: Result := FloatMatrix(datacontainer.StdData[ord(stdNRate)])[iYear, iAge];
               1: Result := FloatMatrix(datacontainer.StdData[ord(stdFRate)])[iYear, iAge];
//               2: Result := FloatMatrix(datacontainer.StdData[ord(stdNFromCatchRate)])[iYear, iAge];
            else
               dsVar := DataSourceVar(ord(dsObsRate) + trunc((S - 2) / datacontainer.ds.count));
               iDs := (S - 2) mod datacontainer.ds.count;
               dsc := datasourcecontainer(datacontainer.ds[iDs]);
               iObsYear := iYear + datacontainer.FirstYear - dsc.FirstYear;
               iObsAge := iAge + datacontainer.FirstAge - dsc.FirstAge;
               ds := FloatMatrix(dsc.dsdata[ord(dsvar)]);
               if (0 <= iObsYear) and (iObsYear <= ds.GetSize(1) - 1) and
                  (0 <= iObsAge) and (iObsAge <= ds.GetSize(2) - 1) then
                  Result := ds[iObsYear, iObsAge]
               else
                  Result := 0
            end;
         end;
   else
      Result := inherited GetInternalValue(I, SeriesVariable, MetaSeries)
   end; // case
end; // YearClassSeries.GetInternalValue


function YearClassSeries.GetShowZeros() : Boolean;
begin
   Result := false;
end;


//////////////////////////////////
// YearClassAgeAxis


function YearClassAgeAxis.GetNumDimensionElms : Integer;
begin
   with YearClassChart(ChartComp) do
      Result := DataContainer.NumElmsInCohort[Cohort];
end; // YearClassAgeAxis.GetNumDimensionElms


function YearClassAgeAxisSeries.GetIntervalName(I : Integer) : string;
var
   Age : Integer;
begin
   // I range : [0..NumDimElms - 1]; // not relative to axis selection.
   with YearClassChart(PrimaryChartAxis.ChartComp) do
      Age := I + MinCategory + DataContainer.FirstAge + DataContainer.FirstAgeIndexInCohort[Cohort];;
   Result := inttostr(Age);
end; // DsAgeAxisSeries.GetIntervalName

end.
